package com.apache.database.db.ibatis;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.apache.cache.service.CacheManager;
import com.apache.cache.service.impl.LoadCacheFactory;
import com.apache.cache.util.Validator;
import com.apache.database.db.BaseDao;
import com.apache.database.model.MethodParam;
import com.apache.database.model.Page;

/**
 * 
 * description: ibatis 持久层的实现
 * 
 */
public class DaoIbatisImpl implements BaseDao {

	@Autowired
	private SqlSessionFactory sqlSessionFactory;//需要注入

	private CacheManager cache;

	public DaoIbatisImpl() {
		cache = LoadCacheFactory.getInstance().getCacheManager("");
	}

	public CacheManager getCache() {
		return cache;
	}

	@SuppressWarnings("rawtypes")
	public IbatisSession getSession(String namespace) {
		return new IbatisSession(sqlSessionFactory);
	}

	/**
	 * description: 批量删除对象
	 * @return true为删除成功；false为删除失败
	 */
	public boolean deleteBath(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			int count = 0;
			List list = (List) param.getVaule();
			for (int i = 0; i < list.size(); i++) {
				count += getSession(param.getSpanceName()).delete(param.getSpanceName(), param.getKey(), list.get(i));
			}
			if (count > 0)
				return true;
		}
		return false;
	}

	/**
	 * description: 批量修改对象值
	 * @return true为修改成功；false为修改失败
	 */
	public boolean editBath(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			int count = 0;
			List list = (List) param.getVaule();
			for (int i = 0; i < list.size(); i++) {
				count += getSession(param.getSpanceName()).update(param.getSpanceName(), param.getKey(), list.get(i));
			}
			if (count > 0)
				return true;
		}
		return false;
	}

	/**
	 * 
	 * description: 批量新增
	 * @return true为新增成功；false为新增失败
	 */
	public boolean insertBath(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			int count = 0;
			List list = (List) param.getVaule();
			count = getSession(param.getSpanceName()).insertBath(list, param.getSpanceName());
			if (count > 0)
				return true;
		}
		return false;
	}

	/**
	 * description: 获取指定sql的count值
	 * @param param 方法参数模型
	 * @return 返回sql执行的记录数
	 */
	public long count(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			return getSession(param.getSpanceName()).count(param.getSpanceName(), param.getKey(), param.getParams());
		}
		return 0;
	}

	/**
	 * description: 删除指定对象
	 * @param param 方法参数模型
	 * @return true为删除成功；false为删除失败
	 */
	public boolean delete(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			int count = 0;
			if (param.isDelete())
				count = getSession(param.getSpanceName()).delete(param.getSpanceName(), param.getKey(),
						param.getParams());
			else
				count = getSession(param.getSpanceName()).update(param.getSpanceName(), param.getKey(),
						param.getParams());
			if (count > 0) {
				if (Validator.isNotNull(param.getCacheId())) {
					cache.removeCacheObject(param.getCacheId());
				}
				return true;
			}
		}
		return false;
	}

	/**
	 * description: 修改对象值
	 * @param param 方法参数模型
	 * @return true为修改成功；false为修改失败
	 */
	public boolean edit(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			int count = 0;
			if (Validator.isEmpty(param.getVaule()))
				count = getSession(param.getSpanceName()).update(param.getSpanceName(), param.getKey(),
						param.getParams());
			else
				count = getSession(param.getSpanceName()).update(param.getSpanceName(), param.getKey(),
						param.getVaule());
			if (count > 0) {
				if (Validator.isNotNull(param.getCacheId())) {
					if (Validator.isEmpty(param.getVaule())) {
						cache.removeCacheObject(param.getCacheId());
					} else {
						cache.createCacheObject(param.getCacheId(), param.getVaule());
					}
				}
				return true;
			}
		}
		return false;
	}

	/**
	 * 
	 * description: 新增单个对象
	 * @param param 方法参数模型
	 * @return true为新增成功；false为新增失败
	 */
	public boolean insert(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			int count = getSession(param.getSpanceName()).insert(param.getSpanceName(), param.getKey(),
					param.getVaule());
			if (count > 0) {
				if (Validator.isNotNull(param.getCacheId())) {
					cache.createCacheObject(param.getCacheId(), param.getVaule());
				}
				return true;
			}
		}
		return false;
	}

	/**
	 * description: 分页查询
	 * @param param 方法参数模型
	 * @return 返回page对象
	 */
	public Page pageSelect(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			return getSession(param.getSpanceName()).selectPage(param.getSpanceName(), param.getKey(), param);
		}
		return new Page();
	}

	/**
	 * description: 列表查询
	 * @param param 方法参数模型
	 * @return 返回sql执行的结果集
	 */
	public List select(MethodParam param) {
		if (Validator.isNotNull(param.getSpanceName())) {
			if (Validator.isNotNull(param.getOrderby())) {
				param.setParams("Qrder-By", param.getOrderby());
			}
			return getSession(param.getSpanceName()).select(param.getSpanceName(), param.getKey(), param.getParams());
		}
		return new ArrayList();
	}

	/**
	 * description: 获取唯一对象实例
	 * @param param 方法参数模型
	 * @return 返回sql执行后的数据对象
	 */
	public Object selectSingle(MethodParam param) {
		Object obj = null;
		if (Validator.isNotNull(param.getSpanceName())) {
			if (Validator.isNotNull(param.getCacheId())) {
				obj = cache.getCacheCloneByKey(param.getCacheId());
			}
			if (Validator.isEmpty(obj)) {
				obj = getSession(param.getSpanceName()).selectSingle(param.getSpanceName(), param.getKey(),
						param.getParams());
			}
		}
		return obj;
	}

	public Object selectById(String spanceName, String key, String infoId, String cacheId) {
		Object obj = null;
		if (Validator.isNotNull(spanceName)) {
			if (Validator.isNotNull(cacheId)) {
				obj = cache.getCacheCloneByKey(cacheId);
			}
			if (Validator.isEmpty(obj)) {
				obj = getSession(spanceName).selectSingle(spanceName, key, infoId);
				if (!Validator.isEmpty(obj) && Validator.isNotNull(cacheId))
					cache.createCacheObject(cacheId, obj);
			}
		}
		return obj;
	}

	public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory = sqlSessionFactory;
	}

}
